import type { Router, RouteLocationNormalized, NavigationGuardNext } from 'vue-router'
import { ref, nextTick } from 'vue'
import NProgress from 'nprogress'
import { useSettingStore } from '@/store/modules/setting'
import { useUserStore } from '@/store/modules/user'
import { useMenuStore } from '@/store/modules/menu'
import { setWorktab } from '@/utils/navigation'
import { setPageTitle, setSystemTheme } from '../utils/utils'
import { registerDynamicRoutes } from '../utils/registerRoutes'
import { AppRouteRecord } from '@/types/router'
import { RoutesAlias } from '../routesAlias'
import { menuDataToRouter } from '../utils/menuToRouter'
import { asyncRoutes } from '../routes/asyncRoutes'
import { loadingService } from '@/utils/ui'
import { useCommon } from '@/composables/useCommon'
import { useWorktabStore } from '@/store/modules/worktab'
import { apiRbacMenuTreeDataUsingPost } from '@/api/apIcaidan'

// 前端权限模式 loading 关闭延时，提升用户体验
const LOADING_DELAY = 100

// 是否已注册动态路由
const isRouteRegistered = ref(false)

// 跟踪是否需要关闭 loading
const pendingLoading = ref(false)

// 用于生成唯一路由名称的计数器
const routeNameCounter = new Map<string, number>()

/**
 * 设置路由全局前置守卫
 */
export function setupBeforeEachGuard(router: Router): void {
  router.beforeEach(
    async (
      to: RouteLocationNormalized,
      from: RouteLocationNormalized,
      next: NavigationGuardNext
    ) => {
      try {
        await handleRouteGuard(to, from, next, router)
      } catch (error) {
        console.error('路由守卫发生错误:', error)
        next('/exception/500')
      }
    }
  )

  // 设置后置守卫以关闭 loading 和进度条
  setupAfterEachGuard(router)
}

/**
 * 设置路由全局后置守卫
 */
function setupAfterEachGuard(router: Router): void {
  router.afterEach(() => {
    // 关闭进度条
    const settingStore = useSettingStore()
    if (settingStore.showNprogress) {
      NProgress.done()
    }

    // 关闭 loading 效果
    if (pendingLoading.value) {
      nextTick(() => {
        loadingService.hideLoading()
        pendingLoading.value = false
      })
    }
  })
}

/**
 * 处理路由守卫逻辑
 */
async function handleRouteGuard(
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext,
  router: Router
): Promise<void> {
  const settingStore = useSettingStore()
  const userStore = useUserStore()

  // 处理进度条
  if (settingStore.showNprogress) {
    NProgress.start()
  }

  // 设置系统主题
  setSystemTheme(to)

  // 处理登录状态
  if (!(await handleLoginStatus(to, userStore, next))) {
    return
  }

  // 处理动态路由注册
  if (!isRouteRegistered.value && userStore.isLogin) {
    await handleDynamicRoutes(to, from, next, router)
    return
  }

  // 处理根路径跳转到首页
  if (userStore.isLogin && isRouteRegistered.value && handleRootPathRedirect(to, next)) {
    return
  }

  // 处理已知的匹配路由
  if (to.matched.length > 0) {
    setWorktab(to)
    setPageTitle(to)
    next()
    return
  }

  // 尝试刷新路由重新注册
  if (userStore.isLogin && !isRouteRegistered.value) {
    await handleDynamicRoutes(to, from, next, router)
    return
  }

  // 未匹配到路由，跳转到 404
  next(RoutesAlias.Exception404)
}

/**
 * 处理登录状态
 */
async function handleLoginStatus(
  to: RouteLocationNormalized,
  userStore: ReturnType<typeof useUserStore>,
  next: NavigationGuardNext
): Promise<boolean> {
  if (!userStore.isLogin && to.path !== RoutesAlias.Login && !to.meta.noLogin) {
    userStore.logOut()
    next(RoutesAlias.Login)
    return false
  }
  return true
}

/**
 * 处理动态路由注册
 */
async function handleDynamicRoutes(
  to: RouteLocationNormalized,
  from: RouteLocationNormalized,
  next: NavigationGuardNext,
  router: Router
): Promise<void> {
  try {
    // 显示 loading 并标记 pending
    pendingLoading.value = true
    loadingService.showLoading()

    await getMenuData(router)

    // 处理根路径跳转
    if (handleRootPathRedirect(to, next)) {
      return
    }

    next({
      path: to.path,
      query: to.query,
      hash: to.hash,
      replace: true
    })
  } catch (error) {
    console.error('处理动态路由时发生错误:', error)
    next('/exception/500')
  }
}

/**
 * 获取菜单数据
 */
async function getMenuData(router: Router): Promise<void> {
  try {
    if (useCommon().isFrontendMode.value) {
      await processFrontendMenu(router)
    } else {
      await processBackendMenu(router)
    }
  } catch (error) {
    handleMenuError(error)
    throw error
  }
}

/**
 * 处理前端控制模式的菜单逻辑
 */
async function processFrontendMenu(router: Router): Promise<void> {
  const menuList = asyncRoutes.map((route) => menuDataToRouter(route))
  const filteredMenuList = filterMenuByRoles(menuList, ['R_SUPER'])

  await new Promise((resolve) => setTimeout(resolve, LOADING_DELAY))

  await registerAndStoreMenu(router, filteredMenuList)
}

/**
 * 处理后端控制模式的菜单逻辑
 */
async function processBackendMenu(router: Router): Promise<void> {
  try {
    const response = await apiRbacMenuTreeDataUsingPost({
      params: { pointsFlag: 1 }
    });

    // 增加数据验证
    if (!response) {
      throw new Error('API返回数据为空');
    }

    // 确保数据格式正确
    let menuData: any[] = [];
    if (response.hasOwnProperty('data') && Array.isArray(response.data)) {
      menuData = response.data;
    } else if (Array.isArray(response)) {
      menuData = response;
    } else {
      throw new Error('API返回数据格式错误，期望为数组');
    }

    routeNameCounter.clear();

    const menuList = menuData
      .map(item => convertBackendMenuToRoute(item, ''))
      .filter(item => item !== null) as AppRouteRecord[];

    await new Promise((resolve) => setTimeout(resolve, LOADING_DELAY));

    await registerAndStoreMenu(router, menuList);
  } catch (error) {
    console.error('处理后端菜单时发生错误:', error);
    throw error;
  }
}

/**
 * 将后端返回的菜单项转换为前端路由格式
 * @param menuItem 后端菜单项
 * @param parentPath 父级路径
 * @returns 路由配置对象
 */
function convertBackendMenuToRoute(menuItem: any, parentPath: string): AppRouteRecord | null {
  // 增加参数校验
  if (!menuItem) {
    return null;
  }
  
  // 如果菜单未启用，直接返回null
  if (menuItem.menuEnableFlag === 0) {
    return null;
  }
  
  let fullPath = '';
  if (menuItem.menuPath) {
    const menuPath = menuItem.menuPath.startsWith('/') ? menuItem.menuPath : `/${menuItem.menuPath}`;
    if (parentPath && menuPath.startsWith(parentPath)) {
      fullPath = menuPath;
    } else if (parentPath && !menuPath.startsWith(parentPath)) {
      fullPath = parentPath + (menuPath.startsWith('/') ? menuPath : `/${menuPath}`);
    } else {
      fullPath = menuPath;
    }
  } else {
    fullPath = parentPath || '';
  }

  // 路由名称唯一性处理
  let routeName = menuItem.menuName || `menu_${menuItem.id || Math.random()}`;
  if (routeNameCounter.has(routeName)) {
    const count = routeNameCounter.get(routeName)! + 1;
    routeNameCounter.set(routeName, count);
    routeName = `${routeName}_${count}`;
  } else {
    routeNameCounter.set(routeName, 0);
  }

  // 组件路径处理
  let componentPath = '';
  if (menuItem.menuComponent) {
    componentPath = menuItem.menuComponent;
  } else if (menuItem.menuFrameFlag === 1 && menuItem.menuFrameUrl) {
    componentPath = '';
  } else if (fullPath && fullPath !== '/') {
    let cleanPath = fullPath;
    if (cleanPath.startsWith('/')) {
      cleanPath = cleanPath.substring(1);
    }
    if (cleanPath.endsWith('/')) {
      cleanPath = cleanPath.slice(0, -1);
    }
    
    // 特殊路径映射表
    const specialPathMap: Record<string, string> = {
      'userarea/userarea': 'userarea/list/index', // 通行记录
      'system/config': 'system/configuration/index', // 系统配置
      'area/areaIndex': 'area/index', // 社区列表
      'actManage/actIndex': 'actManage/index', // 活动详情
      'postStation/postStationIndex': 'postStation/index', // 驿站列表
      'ticket/TicketIndex': 'ticket/index', // 报事列表
      'help/HelpRecord': 'help/record' // 求助记录
    };
    
    // 如果在特殊路径映射表中，则直接使用映射的路径
    if (specialPathMap[cleanPath]) {
      componentPath = specialPathMap[cleanPath];
    } else {
      componentPath = cleanPath;
    }
  } else {
    componentPath = 'Layout'; 
  }

  const route: AppRouteRecord = {
    name: routeName,
    path: fullPath,
    component: componentPath === 'Layout' ? RoutesAlias.Layout : componentPath,
    meta: {
      title: menuItem.menuName || '',
      icon: menuItem.menuIcon || '',
      isHide: menuItem.menuVisibleFlag === 0,
      link: menuItem.menuFrameFlag === 1 ? menuItem.menuFrameUrl : undefined,
      roles: menuItem.menuWebPerms ? [menuItem.menuWebPerms] : undefined,
      authMark: menuItem.menuApiPerms || undefined
    },
    children: [],
    // 保存原始数据供后续使用
    rawData: menuItem
  };

  // 添加严格校验
  if (!route.path) {
    return null;
  }

  // 子菜单递归处理
  if (menuItem.children && Array.isArray(menuItem.children) && menuItem.children.length > 0) {
    route.children = menuItem.children
      .map((child: any) => convertBackendMenuToRoute(child, fullPath))
      .filter(child => child !== null) as AppRouteRecord[]; // 过滤掉null值并断言类型
  }

  return route;
}

/**
 * 递归过滤空菜单项
 */
function filterEmptyMenus(menuList: AppRouteRecord[]): AppRouteRecord[] {
  return menuList
    // 先过滤掉null项
    .filter(item => item !== null)
    .map((item) => {
      if (item.children && item.children.length > 0) {
        const filteredChildren = filterEmptyMenus(item.children);
        return { ...item, children: filteredChildren };
      }
      return item;
    })
    .filter((item) => {
      const hasPath = !!item.path;
      const hasMetaLink = !!item.meta?.link;
      
      // 如果有路径或者有外链链接，则保留
      return hasPath || hasMetaLink;
    });
}

/**
 * 注册路由并存储菜单数据
 */
async function registerAndStoreMenu(router: Router, menuList: AppRouteRecord[]): Promise<void> {
  const menuStore = useMenuStore();

  // 清空旧数据
  menuStore.setMenuList([]);

  // 校验有效性
  if (!isValidMenuList(menuList)) {
    throw new Error('获取菜单列表失败，请重新登录');
  }

  // 过滤无效菜单
  const list = filterEmptyMenus(menuList);

  // 防止重复注册
  if (isRouteRegistered.value) {
    return;
  }

  // 检查重复路径
  const seenPaths = new Set<string>();
  const validRoutes = list.filter(route => {
    // 增加路径校验
    if (!route.path) {
      return false;
    }
    
    if (seenPaths.has(route.path)) {
      return false;
    }
    seenPaths.add(route.path);
    return true;
  });

  // 注册动态路由
  registerDynamicRoutes(router, validRoutes);
  isRouteRegistered.value = true;

  // 设置菜单列表
  menuStore.setMenuList(validRoutes);

  // 触发 worktab 校验
  useWorktabStore().validateWorktabs(router);
}

/**
 * 处理菜单相关错误
 */
function handleMenuError(error: unknown): void {
  console.error('菜单处理错误:', error);
  useUserStore().logOut();
  throw error instanceof Error ? error : new Error('获取菜单列表失败，请重新登录');
}

/**
 * 根据角色过滤菜单
 */
const filterMenuByRoles = (menu: AppRouteRecord[], roles: string[]): AppRouteRecord[] => {
  // 增加参数校验
  if (!Array.isArray(menu) || !Array.isArray(roles)) {
    return [];
  }
  
  return menu.reduce((acc: AppRouteRecord[], item) => {
    // 增加项校验
    if (!item) {
      return acc;
    }
    
    const itemRoles = item.meta?.roles;
    const hasPermission = !itemRoles || itemRoles.some((role) => roles?.includes(role));

    if (hasPermission) {
      const filteredItem = { ...item };
      if (filteredItem.children?.length) {
        filteredItem.children = filterMenuByRoles(filteredItem.children, roles);
      }
      acc.push(filteredItem);
    }

    return acc;
  }, []);
};

/**
 * 验证菜单列表是否有效
 */
function isValidMenuList(menuList: AppRouteRecord[]): boolean {
  return Array.isArray(menuList);
}

/**
 * 重置路由相关状态
 */
export function resetRouterState(): void {
  isRouteRegistered.value = false;
  const menuStore = useMenuStore();
  menuStore.removeAllDynamicRoutes();
  menuStore.setMenuList([]);
  routeNameCounter.clear();
}

/**
 * 处理根路径跳转到首页
 */
function handleRootPathRedirect(to: RouteLocationNormalized, next: NavigationGuardNext): boolean {
  if (to.path === '/') {
    const { homePath } = useCommon();
    if (homePath.value && homePath.value !== '/') {
      next({ path: homePath.value, replace: true });
      return true;
    } else {
      next({ path: '/dashboard/console', replace: true });
      return true;
    }
  }
  return false;
}